#include <iostream>
#include <string>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>

typedef websocketpp::server<websocketpp::config::asio> wsserver_t;

void Print(const std::string &str)
{
    std::cout << str << std::endl;
}

// typedef lib::function<void(connection_hdl)> open_handler;
void http_callback(wsserver_t *srv, websocketpp::connection_hdl hdl) // 给客户端返回一个 hello world 的页面
{
    // 获取通讯连接对象
    wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);
    std::cout << conn->get_request_body() << std::endl; // 打印正文
    // 获取request对象
    websocketpp::http::parser::request req = conn->get_request();
    std::cout << "method: " << req.get_method() << std::endl; // 打印method
    std::cout << "uri: " << req.get_uri() << std::endl;       // 打印uri

    std::string body = "<html><body><h1>hello world</h1></body></html>"; // hello world页面
    conn->set_body(body);                                                // 响应页面
    conn->append_header("Content-Type", "text/html");                    // 添加头部字段
    conn->set_status(websocketpp::http::status_code::ok);                // 设置相应状态码
    srv->set_timer(5000, std::bind(Print, "timer test"));
}

// typedef lib::function<void(connection_hdl)> close_handler;
void wsopen_callback(wsserver_t *srv, websocketpp::connection_hdl hdl)
{
    std::cout << "websocket握手成功." << std::endl;
}

// typedef lib::function<void(connection_hdl)> http_handler;
void wsclose_callback(wsserver_t *srv, websocketpp::connection_hdl hdl)
{
    std::cout << "websocket连接断开." << std::endl;
}

// typedef lib::function<void(connection_hdl,message_ptr)>message_handler;
// typedef typename connection_type::message_ptr message_ptr; -- server继承了endpoint
void wsmessage_callback(wsserver_t *srv, websocketpp::connection_hdl hdl, wsserver_t::message_ptr msg)
{
    // 获取通讯连接对象
    wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);

    std::cout << "wsmsg: " << msg->get_payload() << std::endl; // 获取客户端发送的数据
    std::string rsp = "client say: " + msg->get_payload();     // 构建发送给用户的rsp
    conn->send(rsp, websocketpp::frame::opcode::text);         // 发送给用户
}

int main()
{
    // 1. 实例化server对象
    wsserver_t wssrv;

    // 2. 设置日志等级
    wssrv.set_access_channels(websocketpp::log::alevel::none);

    // 3. 初始化asio调度器
    wssrv.init_asio();
    /*设置是否启⽤地址重⽤*/
    wssrv.set_reuse_addr(true);

    // 4. 设置回调函数
    /*http请求回调处理函数*/
    wssrv.set_http_handler(std::bind(http_callback, &wssrv, std::placeholders::_1));
    /*websocket握⼿成功回调处理函数*/
    wssrv.set_open_handler(std::bind(wsopen_callback, &wssrv, std::placeholders::_1));
    /*websocket连接关闭回调处理函数*/
    wssrv.set_close_handler(std::bind(wsclose_callback, &wssrv, std::placeholders::_1));
    /*websocket消息回调处理函数*/
    wssrv.set_message_handler(std::bind(wsmessage_callback, &wssrv, std::placeholders::_1, std::placeholders::_2));

    // 5. 设置监听端口
    wssrv.listen(8085);

    // 6. 开始获取新链接
    wssrv.start_accept();

    // 7. 启动服务器
    wssrv.run();

    return 0;
}